/**
 * @file 常用工具集合
 * @author Monet
 */
import ajax from "./request";
/**
 * @description 手机号验证
 * @param {string} str 需要验证的字符串
 * @returns {boolean}
 */
export function isPhone(str: string): boolean {
    const myreg = /^[1][3,4,5,6,7,8][0-9]{9}$/;
    return myreg.test(str);
}
/**
 * @description 生成占位图，前期开发用
 * @param {(number | string)} w 占位宽度
 * @param {(number | string)=} h 占位高度
 * @returns {string} 返回占位图地址
 */
export const placeImage = (w: number | string, h = w): string =>
	`http://placehold.it/${w}x${h}`;
/**
 * @description rpx值转px值
 * @param {number} rpx rpx
 * @returns {number} 返回px值
 */
export function rpx2px(rpx: number): number {
    const { windowWidth } = wx.getSystemInfoSync();
    return (rpx / 750) * windowWidth;
}
/**
 * @description px值转rpx值
 * @param {number} px px
 * @returns {number} 返回rpx值
 */
export function px2rpx(px: number): number {
    const { windowWidth } = wx.getSystemInfoSync();
    return (px * 750) / windowWidth;
}
/**
 * @description 获取列表的封装方法，需绑定所在页面实例的this
 * @param {!Object} config 获取列表配置
 * @param {string} config.dataKeyName 返回data的键名
 * @param {string} config.localKeyName 实例的键名
 * @param {string} config.url 请求地址
 * @param {!Object=} config.data 请求的额外数据，可覆盖实例属性
 * @param {number=} config.pageNum 页码，该配置优先于实例
 * @param {number=} config.pageSize 每页数量，该配置优先于实例
 * @param {Function=} config.callback 成功回调
 */
interface GetListConfig {
    /** 返回data的键名 */
    dataKeyName: string;
    /** 实例的键名 */
    localKeyName: string;
    /** 请求地址 */
    url: string;
    /** 请求的额外数据，可覆盖实例属性 */
    data?: object;
    /** 每页数量，该配置优先于实例 */
    pageNum?: number;
    /** 每页数量，该配置优先于实例 */
    pageSize?: number;
    /** 成功回调 */
    callback?: Function;
}
export function getList(this: any, config: GetListConfig): void {
    const { dataKeyName, localKeyName, url } = config;
    const pageNum = config.pageNum || this.data[localKeyName].pageNum;
    const pageSize = config.pageSize || this.data[localKeyName].pageSize || 10;
    const data = config.data || {};
    const { list, hasNext }: { list: object[]; hasNext: boolean } = this.data[
        localKeyName
    ];
    if (!hasNext) {
        return;
    }
    ajax({
        url,
        data: Object.assign(
            {},
            { page: pageNum, rows: pageSize, row: pageSize },
            data
        )
    }).then(({ code, data }) => {
        if (code !== 0 || !data) {
            return;
        }
        const dotIndex = dataKeyName.indexOf(".");
        const listData: Array<object> =
            dotIndex > -1
                ? data[dataKeyName.substring(0, dotIndex)][
                      dataKeyName.substring(dotIndex + 1)
                  ]
                : data[dataKeyName];
        if (
            code === 0 &&
            listData &&
            Array.isArray(listData) &&
            listData.length > 0
        ) {
            this.setData(
                {
                    [`${localKeyName}.list`]: list.concat(listData),
                    [`${localKeyName}.pageNum`]: pageNum + 1
                },
                () => {
                    if (config.callback) {
                        config.callback();
                    }
                }
            );
        } else {
            this.setData({
                [`${localKeyName}.hasNext`]: false
            });
        }
    });
}
/**
 * @description 微信自带轻提示
 * @param {string} str 提示文字
 */
export const toast = (str: string): void => {
    wx.showToast({
        title: str,
        icon: "none"
    });
};
/**
 * @description 将wx原生方法转化为Promise
 * @param {Function} func 转换函数
 */
export function promisify(func: Function): Function {
    return (options: IAnyObject = {}, ...params: any): Promise<any> => {
        return new Promise((resolve, reject) => {
            func(
                Object.assign({}, options, { success: resolve, fail: reject }),
                ...params
            );
        });
    };
}

/**
 * 函数防抖
 * @param fn 
 * @param interval 
 */
export function debounce<F extends (...params: any[]) => void>(fn: F, delay: number) {
	let timeoutID: number;
	return function(this: any, ...args: any[]) {
	  clearTimeout(timeoutID);
	  timeoutID = setTimeout(() => fn.apply(this, args), delay);
	} as F;
  }
/**
 * 倒计时事件处理
 * @param t 时间毫秒
 * @param callback 每次倒计时回调
 * @param complete 倒计时结束回调
 */
export const countdownHandler = (/** 倒计时时间 */t: number, /** 时间变化回调 */ callback: (...param: any[]) => void, complete: () => void): void => {
	if (t <= 0) {
		complete()
	} else {
		const days = Math.floor(t / 24 / 60 / 60 / 1000);
		const hours = Math.floor(t/ 1000 / 60 / 60 % 24)
		const minutes = Math.floor(t/ 1000 / 60 % 60)
		const seconds = Math.floor(t/ 1000 % 60)
		callback({days, hours, minutes, seconds})
		setTimeout(() => { 
			countdownHandler(t - 1000, callback, complete)
		}, 1000)
	}
}